package com.troll.dayily.view.lrc

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.media.MediaPlayer
import android.util.AttributeSet
import android.view.View
import com.troll.dayily.R

/**
 *

 * @Author:   TangPeng
 * @Time:     2021/7/5
 * @Remark:  歌词View
 */
class LrcView @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attributeSet, defStyleAttr) {

    private var highLineTextColor: Int = 0
    private var lrcTextColor: Int = 0
    private var lineSpace: Int = 0
    private var textSize: Int = 0


    /**
     * 歌词画笔
     */
    private val textPaint by lazy {
        Paint().apply {
            style = Paint.Style.FILL
            isAntiAlias = true
            color = lrcTextColor
            textSize = textSize
            textAlign = Paint.Align.CENTER
        }
    }

    private val currentTextPain by lazy {
        Paint().apply {
            style = Paint.Style.FILL
            isAntiAlias = true
            color = highLineTextColor
            textSize = textSize
            textAlign = Paint.Align.CENTER
        }
    }

    private var cWidth: Int = 0
    private var cHeight: Int = 0
    private var lrc: MutableList<LrcBean>? = null
    private var player: MediaPlayer? = null
    private var currentPosition: Int = 0
    private var lastPosition: Int = 0

    init {
        val typeArray = context.obtainStyledAttributes(attributeSet, R.styleable.LrcView)
        highLineTextColor = typeArray.getColor(R.styleable.LrcView_highLineTextColor, Color.BLACK)
        lrcTextColor = typeArray.getColor(R.styleable.LrcView_lrcTextColor, Color.RED)

        val fontScale = context.resources.displayMetrics.scaledDensity
        val scale = context.resources.displayMetrics.density
        textSize =
            typeArray.getDimensionPixelSize(R.styleable.LrcView_textSize, (16 * fontScale).toInt())
//        lineSpace =
//            typeArray.getDimensionPixelSize(R.styleable.LrcView_lineSpacing, (30 * scale).toInt())
        typeArray.recycle()
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        if (canvas == null) return
        measuredWidthAndHeight()

        scrollLrc()// 滚动歌词
        getCurrentPosition() // 获取当前歌词的位置
        drawLrc(canvas) //画歌词
        postInvalidateDelayed(100) // 延迟0.1S刷新
    }

    private fun drawLrc(canvas: Canvas) {
        lrc?.forEachIndexed { index, lrcBean ->
            if (1 == currentPosition) {
                canvas.drawText(
                    lrcBean.lrc,
                    (cWidth / 2).toFloat(),
                    (cHeight / 2 + index * lineSpace).toFloat(),
                    textPaint
                );
            } else {
                canvas.drawText(
                    lrcBean.lrc,
                    (cWidth / 2).toFloat(),
                    (cHeight / 2 + index * lineSpace).toFloat(),
                    currentTextPain
                );
            }
        }

    }

    private fun getCurrentPosition() {
        val currentTime = player?.currentPosition ?: 0
        lrc?.let {
            if (currentTime < it[0].start || currentTime > 10 * 60 * 1000) {
                currentPosition = 0
                return
            } else if (currentTime > it[it.size - 1].start) {
                currentPosition = it.size - 1
            }
            for (i in 0..it.size) {
                if (currentTime >= it[i].start && currentTime <= it[i].end) {
                    currentPosition = i
                }
            }
        }


    }

    private fun scrollLrc() {
        lrc?.let {
            val startTime = it[currentPosition].start
            val currentTime = player?.currentPosition ?: 0
            val y = if ((currentTime - startTime) > 500) {
                currentPosition * lineSpace
            } else {
                lastPosition * lineSpace + (currentPosition - lastPosition) * lineSpace * ((currentTime - startTime) / 500f)
            }
            scrollTo(0, y as Int)
            if (scrollY == currentPosition * lineSpace) {
                lastPosition = currentPosition;
            }

        }

    }

    private fun measuredWidthAndHeight() {
        cWidth = measuredWidth
        cHeight = measuredHeight
    }

    fun setLrc(lrc: String) {
        this.lrc = LrcUtil.castLrc(lrc)
    }

    fun setPlayer(player: MediaPlayer) {
        this.player = player
    }
}